package br.com.guarana.business.service;

import br.com.guarana.business.model.Usuario;
import br.com.guarana.util.Util;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.persistence.Query;

/**
 *
 * @author 
 */
public class UsuarioService extends PadraoService {

    public void salvar(Usuario usuario) {
        try {
            this.getDAO().getEntityManager().getTransaction().begin();

            //busca registro do banco e verifica se senha é diferente da atual, se sim encripta            
            Usuario objBanco = findUsuario(usuario.getId());
            if ((objBanco == null) || (!objBanco.getSenha().equals(usuario.getSenha()))) {
                usuario.setSenha(encripta(usuario.getSenha()));
            }

            //Não deixa inserir com mesmo username
            if (!isUniqueLogin(usuario)) {
                throw new Exception("Erro: O 'username' já esta sendo usado por outro Usuário.");
            }

            this.getDAO().salvar(usuario);
            this.getDAO().getEntityManager().getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            this.getDAO().getEntityManager().getTransaction().rollback();
        }
    }

    public void excluir(Usuario usuario) {
        try {
            this.getDAO().getEntityManager().getTransaction().begin();
            this.getDAO().excluir(usuario);
            this.getDAO().getEntityManager().getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            this.getDAO().getEntityManager().getTransaction().rollback();
        }
    }

    public Usuario findUsuario(int id) {
        return (Usuario) this.getDAO().find(Usuario.class, id);
    }
    
    public List<Usuario> buscaTodosUsuarios() {
        StringBuilder sFrase = new StringBuilder("SELECT r FROM Usuario r ORDER BY r.nome");
        Query query = this.getDAO().getEntityManager().createQuery(sFrase.toString());
        query.setHint("toplink.refresh", "true");
        List<Usuario> listaUsuario = query.getResultList();
        return listaUsuario;
    }
    
    public List<Usuario> buscaUsuarios(String tipoPerfil, String nome) {
        //busca HQL
        StringBuilder sFrase = new StringBuilder("SELECT r FROM Usuario r");
        

        if (nome != null) {
            sFrase.append(Util.colocaWhereOuAnd(sFrase.toString()) + " UPPER(r.nome) LIKE '%" + nome.toUpperCase().trim() + "%'");
        }

        //order by
        sFrase.append(" ORDER BY r.nome");

        //query
        Query query = this.getDAO().getEntityManager().createQuery(sFrase.toString());
        query.setHint("toplink.refresh", "true");
        List<Usuario> listaUsuario = query.getResultList();

        return listaUsuario;
    }
    

    public Usuario logar(String username, String senha) {
        //seta locale brasileiro
        Locale locale = new Locale("pt", "BR");
        Locale.setDefault(locale);

        //registro logado
        Usuario registro = null;

        //busca por usuário e senha criptografada
        Query query = this.getDAO().getEntityManager().createQuery("SELECT a FROM Usuario a WHERE a.username = :username AND a.senha = :senha");
        query.setParameter("username", username);
        query.setParameter("senha", encripta(senha));
        query.setHint("toplink.refresh", "true");

        try {
            registro = (Usuario) query.getSingleResult();            
            this.getDAO().getEntityManager().clear();

            //atualiza último acesso
            this.getDAO().getEntityManager().getTransaction().begin();
            Usuario registroUltimoAcesso = this.findUsuario(registro.getId());
            registroUltimoAcesso.setDataHoraUltimoAcesso(new Date());
            this.getDAO().salvar(registroUltimoAcesso);
            this.getDAO().getEntityManager().getTransaction().commit();

        } catch (Exception e) {
            registro = null;
            System.out.println("Erro ao logar: Usuário " + username + " não encontrado.");
        }                

        //pelo tipoPerfil dá pra saber se é administrador ou comum
        return registro;
    }

    //Método para não deixar cadastrar o mesmo username
    public boolean isUniqueLogin(Usuario u) {
        Query query = this.getDAO().getEntityManager().createNamedQuery("Usuario.uniqueLogin");
        query.setParameter("username", u.getUsername());
        query.setParameter("id", u.getId());
        List<Usuario> registro = null;

        try {
            registro = query.getResultList();

            if (registro != null && registro.size() > 0) {
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            return true;
        }
    }

    //método que criptografa a senha do usuário
    public static String encripta(String senha) {
        return Util.calculaHashMD5(senha);
    }
        
    /*
     * TESTES TESTES TESTES TESTES TESTES TESTES TESTES TESTES
     */

    public static void main(String[] args) {
        UsuarioService main = new UsuarioService();    
        main.buscaTodosUsuarios();
        main.buscaUsuarios("A", "admin");
        
        Usuario usu = main.logar("GUARANA", "1");
    }
}

